package com.well.kernel.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.log4j.Logger;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Copyright &copy; Well All rights reserved.
 * Author:Well
 * Date:2017-02-08
 * Description:日期的利用类
 *      日期时间的处理方法可以也可以参考 org.apache.commons.lang3.time.DateUtils 和 org.apache.commons.lang3.time.DateFormatUtils
 */

public class DateUtil
{
    private static Logger logger= Logger.getLogger(DateUtil.class);

    /* 日期时间的转换格式 */
    public static final String DATE_TIME_PATTERN="yyyy-MM-dd HH:mm:ss";

    /* 日期的转换格式 */
    public static final String DATE_PATTERN="yyyy-MM-dd";

    /* 时间的转换格式 */
    public static final String TIME_PATTERN="HH:mm:ss";

    /* 年份的转换格式 */
    public static final String YEAR_PATTERN="yyyy";

    /* 月份的转换格式 */
    public static final String MONTH_PATTERN="MM";

    /* 天的转换格式 */
    public static final String DAY_PATTERN="dd";

    /* 时的转换格式 */
    public static final String HOUR_PATTERN="HH";

    /* 分的转换格式 */
    public static final String MINUTE_PATTERN="mm";

    /* 秒的转换格式 */
    public static final String SECOND_PATTERN="ss";

    /* 时区，东八区，即北京时间 */
    public static final String TIME_ZONE="GMT+8";

    /**
     * 构造函数私有化
     */
    private DateUtil(){}

    /**
     * 获取当前的日期时间
     * @return
     */
    public static String getDateTime()
    {
        return format(new Date(), DATE_TIME_PATTERN);
    }

    /**
     * 获取当前日期
     * @return
     */
    public static String getDate()
    {
        return format(new Date(), DATE_PATTERN);
    }

    /**
     * 获取当前时间
     * @return
     */
    public static String getTime()
    {
        return format(new Date(), TIME_PATTERN);
    }

    /**
     * 获取当前年份
     * @return
     */
    public static String getYear()
    {
        return format(new Date(),YEAR_PATTERN);
    }

    /**
     * 获取当前月份
     * @return
     */
    public static String getMonth()
    {
        return format(new Date(),MONTH_PATTERN);
    }

    /**
     * 获取当前天
     * @return
     */
    public static String getDay()
    {
        return format(new Date(),DAY_PATTERN);
    }

    /**
     * 获取当前小时
     * @return
     */
    public static String getHour()
    {
        return format(new Date(),HOUR_PATTERN);
    }

    /**
     * 获取当前分钟
     * @return
     */
    public static String getMinute()
    {
        return format(new Date(),MINUTE_PATTERN);
    }

    /**
     * 获取当前秒钟
     * @return
     */
    public static String getSecond()
    {
        return format(new Date(),SECOND_PATTERN);
    }

    /**
     * 将Date类型格式化成指定格式的字符串类型
     * @param date
     * @param format 格式
     * @return
     */
    public static String format(Date date,String format)
    {
        String s=null;
        if(null!=date && StringUtils.isNotBlank(format))
        {
            s= DateFormatUtils.format(date, format);
        }
        else
        {
            logger.error("参数不能为空！");
        }
        return s;
    }

    /**
     * 根据字符串模式，将字符串的日期时间转换为Date类型
     * 默认支持的字符串模式为：yyyy-MM-dd、yyyy-MM-dd HH:mm:ss、yyyyMMdd、yyyyMMddHHmmss、yyyy/MM/dd、yyyy/MM/dd HH:mm:ss
     * 如果是其它格式，可以使用 org.apache.commons.lang3.time.DateUtils.parseDate(s,formats) 进行转换
     * @param s
     * @return
     */
    public static Date parse(String s){
        if(StringUtils.isNotBlank(s)){ // 时间格式为 yyyy-MM-dd
            if(s.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")){
                return DateUtil.parse(s, DATE_PATTERN);
            }
            if(s.matches("^\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}$")){ // 时间格式为 yyyy-MM-dd HH:mm:ss
                return DateUtil.parse(s, DATE_TIME_PATTERN);
            }
            if(s.matches("^\\d{4}\\d{1,2}\\d{1,2}$")){ // 时间格式为 yyyyMMdd
                return DateUtil.parse(s, "yyyyMMdd");
            }
            if(s.matches("^\\d{4}\\d{1,2}\\d{1,2}\\d{1,2}\\d{1,2}\\d{1,2}$")){ // 时间格式为 yyyyMMddHHmmss
                return DateUtil.parse(s, "yyyyMMddHHmmss");
            }
            if(s.matches("^\\d{4}/\\d{1,2}/\\d{1,2}$")){
                return DateUtil.parse(s,"yyyy/MM/dd");
            }
            if(s.matches("^\\d{4}/\\d{1,2}/\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}$")){
                return DateUtil.parse(s,"yyyy/MM/dd HH:mm:ss");
            }
            logger.warn("无法匹配的时间格式");
        }
        return null;
    }

    /**
     * 将字符串类型的日期时间转换为Date类型
     * @param s 字符串的日期时间
     * @param formats 格式数组
     * @return
     * @throws
     */
    public static Date parse(String s,String ... formats)
    {
        Date date=null;
        try {
            date=DateUtils.parseDate(s,formats);
        }
        catch (ParseException e){
            logger.error(e);
        }
        return date;
    }

    /**
     * 判断年份是否为闰年
     * @param year
     * @return
     */
    public static boolean isLeapYear(String year)
    {
        return isLeapYear(Integer.parseInt(year));
    }

    /**
     * 判断年份是否为闰年
     * @param year 年份
     * @return
     */
    public static boolean isLeapYear(int year)
    {
        boolean leapYear=((year%400)==0);
        if(!leapYear)
        {
            leapYear=((year%4)==0) && ((year%100)!=0);
        }
        return leapYear;
    }

    /**
     * 获取日期集合
     * @param start 开始日期
     * @param end 结束日期
     * @return
     */
    public static List<String> getDateList(String start,String end){
        Date s=parse(start);
        Date e=parse(end);
        return getDateList(s,e);
    }

    /**
     * 获取日期集合
     * @param s 开始日期
     * @param e 结束日期
     * @return
     */
    public static List<String> getDateList(Date s,Date e){
        List<String> dateList=new ArrayList<String>();
        Calendar calendar = Calendar.getInstance();
        while(s.getTime()<= e.getTime()){
            dateList.add(format(s,DATE_PATTERN));
            calendar.setTime(s);
            calendar.add(Calendar.DATE,1);
            s =calendar.getTime();
        }
        return dateList;
    }

    /**
     * 获取当天的开始时间
     * @return
     */
    public static String getStart(){
        return format(getStartDate(new Date()),DATE_TIME_PATTERN);
    }

    /**
     * 获取指定日期那天的开始时间，yyyy-MM-dd 00:00:00
     * @param s
     * @return
     */
    public static String getStart(String s){
        Date date=parse(s);
        return getStart(date);
    }

    /**
     * 获取指定日期那天的开始时间，yyyy-MM-dd 00:00:00
     * @param date
     * @return
     */
    public static String getStart(Date date){
        return format(getStartDate(date),DATE_TIME_PATTERN);
    }

    /**
     * 获取指定日期那天的开始时间
     * @param date
     * @return 返回 Date 类型的日期
     */
    private static Date getStartDate(Date date){
        Calendar calendar=Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
        return calendar.getTime();
    }

    /**
     * 获取当天的结束时间，yyyy-MM-dd 23:59:59
     * @return
     */
    public static String getEnd(){
        return format(getEndDate(new Date()),DATE_TIME_PATTERN);
    }

    /**
     * 获取指定时间那天的结束时间，yyyy-MM-dd 23:59:59
     * @param s
     * @return
     */
    public static String getEnd(String s){
        Date date=parse(s);
        return getEnd(date);
    }

    /**
     * 获取指定时间那天的结束时间
     * @param date
     * @return
     */
    public static String getEnd(Date date){
        return format(getEndDate(date),DATE_TIME_PATTERN);
    }

    /**
     * 获取指定时间那天的结束时间
     * @param date
     * @return 返回 Date 类型日期
     */
    private static Date getEndDate(Date date){
        Calendar calendar=Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY,23);
        calendar.set(Calendar.MINUTE,59);
        calendar.set(Calendar.SECOND,59);
        return calendar.getTime();
    }

    public static int compareTo(String s1,String s2){
        Date d1=parse(s1);
        Date d2=parse(s2);
        return d1.compareTo(d2);
    }

}
